/**
 * 
 */
package org.dragonfire.dasm.directives;

import java.util.ArrayList;

import org.dragonfire.dasm.Command;
import org.dragonfire.dasm.Listing;
import org.dragonfire.dasm.DirectiveManager.Directive;
import org.dragonfire.parser.Equation;
import org.dragonfire.util.DMath;

/**
 * Inserts raw data into the output file using 2-byte words. Each numerical
 * argument passed is truncated to two bytes and inserted while each string
 * argument is divided up into individual chars, each of which is inserted as
 * it's ascii value.<br />
 * <br />
 * Format:<br />
 * <code>#DW <i>&lt;arg1&gt;</i>[,<i>&lt;arg2&gt;</i>[,<i>...</i>]]</code><br />
 * <br />
 * Parameters:<br />
 * <table>
 * <tr>
 * <td><code>arg1</code></td>
 * <td> (Integer/String) The data to be placed into the output file. If an
 * integer is passed, then the integer is truncated to the first 16 bits and
 * that is used. If a string is passed, then each character in the string is
 * truncated to a word and inserted. This allows for a full unicode character
 * set to be used</td>
 * </tr>
 * </table><br />
 * Errors:<br />
 * <i>None</i>
 * 
 * @see Db
 * @author Darth Android
 * @version 2.0
 */
// TODO finish documenting errors
public class Dw extends Directive {

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void pass2(Listing lst, Command c) {
		ArrayList<java.lang.Byte> data = new ArrayList<java.lang.Byte>();
		for (String s : c.getParams()) {
			byte[] dat = new byte[0];
			if (Equation.isString(s)) {
				s = evalString(s);
				for (char ch : s.toCharArray()) {
					dat = DMath.trimBin((int) ch, 2);
					if (lst.isLSFirst()) {
						data.add(dat[1]);
						data.add(dat[0]);
					}
					else {
						data.add(dat[0]);
						data.add(dat[1]);
					}
				}
			}
			else {
				dat = DMath.trimBin(evalInt(s), 2);
				if (lst.isLSFirst()) {
					data.add(dat[1]);
					data.add(dat[0]);
				}
				else {
					data.add(dat[0]);
					data.add(dat[1]);
				}
			}
		}
		lst.setMCode(data);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ArrayList<Listing> pass1(Command c) {
		int length = 0;
		for (String s : c.getParams()) {
			if (Equation.isString(s)) {
				length += s.length() - 2;
			}
			else
				length++;
		}
		length *= 2;
		ArrayList<Listing> list = new ArrayList<Listing>();
		Listing l = new Listing(length, c);
		list.add(l);
		return list;
	}
}
